﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Security.AccessControl;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Forms;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using Application = System.Windows.Application;
using MessageBox = System.Windows.MessageBox;
using OpenFileDialog = Microsoft.Win32.OpenFileDialog;
using RichTextBox = System.Windows.Controls.RichTextBox;
using SaveFileDialog = Microsoft.Win32.SaveFileDialog;
using TabControl = System.Windows.Controls.TabControl;
using WebBrowser = System.Windows.Controls.WebBrowser;

namespace iSmartCreatorApp
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private static string filePath; //Path to file (with filename)
        public static string fileName; //File name
        public static string projectFileDirectory; //Path to directory of file (without filename)
        public static Dictionary<string, string> dictionary; //Hashtable
        public static TabItem currentTab; //Selected TabItem
        public static RichTextBox currentRTBHtml; //RichTextBox HTML-code of selected TabItem
        public static RichTextBox currentRTBUser; //RichTextBox User's text of selected TabItem
        public static WebBrowser currentWebBrowser;
        public static TabControl addedTabControl;
        public static Dictionary<Image, string> ImageDict { get; set; }
        public static Dictionary<string, string> LinkDict { get; set; } 

        public static TreeViewItem CurrentTvi { get; set; }

        public static string HtmlText { get; set; }
        public static string UserText { get; set; }

        //Constructor
        public MainWindow()
        {
            InitializeComponent();

            TabControlMain.Visibility = Visibility.Hidden;
            MenuItemCloseAll.IsEnabled = false;
            MenuItemAddSpecial.IsEnabled = false;
            MenuItemSave.IsEnabled = false;
            MenuItemSaveAs.IsEnabled = false;
            MenuItemOpenFile.IsEnabled = false;
            BtnNew.IsEnabled = false;
            BtnOpen.IsEnabled = false;
            BtnSave.IsEnabled = false;
            MenuItemChangeTitle.IsEnabled = false;
            BtnUndo.IsEnabled = false;
            BtnRedo.IsEnabled = false;
            BtnLink.IsEnabled = false;
            BtnImage.IsEnabled = false;
            BtnTable.IsEnabled = false;

            LinkDict = new Dictionary<string, string>();
            CreateEmptyHtml();
            CreateLibrary();
        }

        //Creating template html-file
        private static void CreateEmptyHtml()
        {
            Stream stream = new FileStream("template.html", FileMode.Create);
            using (stream)
            {
                var streamWriter = new StreamWriter(stream);
                using (streamWriter)
                {
                    streamWriter.Write(
                        "<$DTD>\n<html$html>\n<head>\n<meta content=\"text/html; charset=ISO-8859-1\"http-equiv=\"content-type\">\n<title>$title</title>\n</head>\n<body>\n</body>\n</html>");
                }
            }

        }

        //Creating hashtable file
        private static void CreateLibrary()
        {
            dictionary = new Dictionary<string, string>();
            dictionary.Add("$title", NewDocument.pageTitle);
            dictionary.Add("$DTD", NewDocument.pageDTD);
            dictionary.Add("$html", NewDocument.pageHtmlType);
            //dictionary.Add("$body", NewDocument.pageBody);

            Stream stream = new FileStream("library.txt", FileMode.Create);
            using (stream)
            {
                var streamWriter = new StreamWriter(stream);
                using (streamWriter)
                {
                    foreach (var d in dictionary)
                    {
                        streamWriter.WriteLine(d.Key + " = " + d.Value);
                    }
                }
            }
        }

        //MenuItem "New Project" Click
        private void MenuItem_Click_1(object sender, RoutedEventArgs e)
        {
            var dirName = new DirectoryNameWindow {Owner = this};
            dirName.ShowDialog();
        }

        //MenuItem "Exit" Click
        private void MenuItem_Click(object sender, RoutedEventArgs e)
        {
            this.Close();
        }

        //MenuItem "Close Project" Click
        private void MenuItem_Click_2(object sender, RoutedEventArgs e)
        {
            if (!TreeViewMain.Items.IsEmpty)
            {
                var result = MessageBox.Show("Close current project? Unsaved files will be lost!", "iSmart Creator",
                                             MessageBoxButton.YesNoCancel);
                if (result == MessageBoxResult.Yes)
                {
                    TreeViewMain.Items.Clear();
                    TabControlMain.Items.Clear();
                    TabControlMain.Visibility = Visibility.Hidden;
                    MenuItemCloseAll.IsEnabled = false;
                    MenuItemAddSpecial.IsEnabled = false;
                    MenuItemSave.IsEnabled = false;
                    MenuItemSaveAs.IsEnabled = false;
                    MenuItemOpenFile.IsEnabled = false;
                    BtnNew.IsEnabled = false;
                    BtnOpen.IsEnabled = false;
                    BtnSave.IsEnabled = false;
                    MenuItemChangeTitle.IsEnabled = false;
                    BtnUndo.IsEnabled = false;
                    BtnLink.IsEnabled = false;
                    BtnImage.IsEnabled = false;
                }
            }
        }

        //MenuItem "Save As..." Click
        private void MenuItem_Click_3(object sender, RoutedEventArgs e)
        {
            if (currentTab != null)
            {
                SaveFileDialog saveFile = new SaveFileDialog
                    {
                        FileName = currentTab.Header.ToString(),
                        DefaultExt = ".html",
                        Filter = "HTML Files (.html)|*.html",
                        Title = "Save page as"
                    };
                var result = saveFile.ShowDialog();

                if (result == true)
                {
                    filePath = saveFile.FileName;
                    fileName = Path.GetFileName(filePath);

                    FileStream stream = new FileStream(filePath, FileMode.Create);
                    using (stream)
                    {
                        string str =
                            new TextRange(currentRTBHtml.Document.ContentStart, currentRTBHtml.Document.ContentEnd).Text;
                        StreamWriter writer = new StreamWriter(stream);

                        using (writer)
                        {
                            writer.Write(str);
                        }
                    }
                }
            }
        }

        //MenuItem "Save" Click
        private void MenuItem_Click_4(object sender, RoutedEventArgs e)
        {
            try
            {
                FileStream stream = new FileStream(projectFileDirectory + "\\" + fileName,
                                                   FileMode.Create);
                using (stream)
                {
                    string str =
                        new TextRange(currentRTBHtml.Document.ContentStart,
                                      currentRTBHtml.Document.ContentEnd).Text;

                    StreamWriter writer = new StreamWriter(stream);

                    using (writer)
                    {
                        writer.Write(str);
                    }
                }
            }
            catch (DirectoryNotFoundException)
            {
                MessageBox.Show("No files have been created!", "iSmart Creator", MessageBoxButton.OK,
                                MessageBoxImage.Error);
            }

        }

        //MenuItem "Open File" Click
        private void MenuItem_Click_5(object sender, RoutedEventArgs e)
        {
            //NewDocument.pageBody = null;
            var openFile = new OpenFileDialog {Filter = "HTML Files (.html)|*.html", Title = "Open HTML File"};

            var result = openFile.ShowDialog();

            if (result == true)
            {
                filePath = openFile.FileName;
                fileName = Path.GetFileName(filePath);

                FileStream stream = new FileStream(filePath, FileMode.Open);

                string str;

                StreamReader reader = new StreamReader(stream);
                using (reader)
                {
                    str = reader.ReadToEnd();
                }

                TabControl control = new TabControl {TabStripPlacement = Dock.Bottom};
                TabItem editor = new TabItem {Header = "editor"};
                TabItem sourceCode = new TabItem {Header = "source code"};
                TabItem preview = new TabItem {Header = "preview"};

                currentRTBHtml = new RichTextBox
                    {
                        IsReadOnly = true,
                        VerticalScrollBarVisibility = ScrollBarVisibility.Auto,
                        HorizontalScrollBarVisibility = ScrollBarVisibility.Auto
                    };
                currentRTBUser = new RichTextBox
                    {
                        VerticalScrollBarVisibility = ScrollBarVisibility.Auto,
                        HorizontalScrollBarVisibility = ScrollBarVisibility.Auto
                    };
                currentWebBrowser = new WebBrowser();
                TabItem item = new TabItem {Header = fileName};

                FlowDocument flow = new FlowDocument();
                Paragraph paragraph = new Paragraph();
                paragraph.Inlines.Add(new Run(str));
                flow.Blocks.Add(paragraph);
                currentRTBHtml.Document = flow;

                editor.Content = currentRTBUser;
                sourceCode.Content = currentRTBHtml;
                preview.Content = currentWebBrowser;

                control.Items.Add(editor);
                control.Items.Add(sourceCode);
                control.Items.Add(preview);

                item.Content = control;
                item.IsSelected = true;
                TabControlMain.Items.Add(item);
                TabControlMain.Visibility = Visibility.Visible;

                TreeViewItem openedItem = new TreeViewItem {Header = fileName};
                DirectoryNameWindow.MainTreeViewItem.Items.Add(openedItem);
                DirectoryNameWindow.MainTreeViewItem.IsExpanded = true;

                MenuItemSave.IsEnabled = true;
                MenuItemSaveAs.IsEnabled = true;
                BtnSave.IsEnabled = true;
                MenuItemChangeTitle.IsEnabled = true;
                BtnLink.IsEnabled = true;
                BtnImage.IsEnabled = true;
                BtnTable.IsEnabled = true;

                try
                {
                    currentRTBUser.Focus();
                    currentRTBUser.TextChanged += currentRTBUser_TextChanged;
                    UserText = new TextRange(currentRTBUser.Document.ContentStart, currentRTBUser.Document.ContentEnd).Text;
                    HtmlText = new TextRange(currentRTBHtml.Document.ContentStart, currentRTBHtml.Document.ContentEnd).Text;
                    currentRTBHtml.TextChanged += currentRTBHtml_TextChanged;
                }
                catch (NullReferenceException)
                {

                }
            }
        }

        //Closing MainWindow
        private void Window_Closing(object sender, CancelEventArgs e)
        {
            var result = MessageBox.Show("Are you shure you want to Quit?", "iSmart Creator",
                                         MessageBoxButton.YesNoCancel);
            if (result == MessageBoxResult.Yes)
            {
                Application.Current.Shutdown();
            }
            else
            {
                e.Cancel = true;
            }
        }

        //MenuItem "Add Special HTML..." click
        private void MenuItem_Click_6(object sender, RoutedEventArgs e)
        {
            var newDoc = new NewDocument {Owner = this};
            newDoc.ShowDialog();

            try
            {
                currentRTBUser.Focus();
                currentRTBUser.TextChanged += currentRTBUser_TextChanged;
                UserText = new TextRange(currentRTBUser.Document.ContentStart, currentRTBUser.Document.ContentEnd).Text;
                HtmlText = new TextRange(currentRTBHtml.Document.ContentStart, currentRTBHtml.Document.ContentEnd).Text;
                currentRTBHtml.TextChanged += currentRTBHtml_TextChanged;
            }
            catch (NullReferenceException)
            {

            }
        }

        //Html Rich Text Box text changed
        void currentRTBHtml_TextChanged(object sender, TextChangedEventArgs e)
        {
            HtmlText = new TextRange(currentRTBHtml.Document.ContentStart, currentRTBHtml.Document.ContentEnd).Text;
            UserText = new TextRange(currentRTBUser.Document.ContentStart, currentRTBUser.Document.ContentEnd).Text;

            string body = FindBody(currentRTBHtml);
            string[] mas;
            string tag = "";
            string reference = "";
            string src = "";

            if (body != null)
            {
                mas = body.Split('\n');

                for (int i = 0; i < mas.Length; i++)
                {
                    for (int j = 0; j < mas[i].Length; j++)
                    {
                        #region <a></a>
                        if (mas[i].StartsWith("<a"))
                        {
                            while (!tag.EndsWith("</a>"))
                            {
                                tag += mas[i][j];
                                j++;
                            }
                            j--;
                            
                            #region <a><img></a>
                            if (tag.Contains("<img"))
                            {
                                {
                                    int index = mas[i].IndexOf("src=", StringComparison.Ordinal);
                                    string str = mas[i].Substring(index);
                                    for (int k = 5; k < str.Length; k++)
                                    {
                                        while (str[k] != '"')
                                        {
                                            src += str[k];
                                            k++;
                                        }
                                        break;
                                    }
                                    if (ImageDict == null)
                                    {
                                        Image image = new Image();
                                        image.Stretch = Stretch.None;
                                        BitmapImage bmp = new BitmapImage(new Uri(src, UriKind.Relative));
                                        image.Source = bmp;
                                        currentRTBUser.BeginChange();
                                        TextPointer tp = currentRTBUser.CaretPosition.GetPositionAtOffset(0,
                                                                                                          LogicalDirection
                                                                                                              .Forward);
                                        InlineUIContainer imageContainer = new InlineUIContainer(image, tp);
                                        currentRTBUser.CaretPosition = imageContainer.ElementEnd;
                                        currentRTBUser.EndChange();
                                        currentRTBUser.Focus();
                                        src = "";
                                    }
                                    else
                                    {
                                        if (ImageDict.ContainsValue(src))
                                        {
                                            src = "";
                                            break;
                                        }
                                        Image image = new Image();
                                        image.Stretch = Stretch.None;
                                        BitmapImage bmp = new BitmapImage(new Uri(src, UriKind.Relative));
                                        image.Source = bmp;
                                        currentRTBUser.BeginChange();
                                        TextPointer tp = currentRTBUser.CaretPosition.GetPositionAtOffset(0,
                                                                                                          LogicalDirection
                                                                                                              .Forward);
                                        InlineUIContainer imageContainer = new InlineUIContainer(image, tp);
                                        currentRTBUser.CaretPosition = imageContainer.ElementEnd;
                                        currentRTBUser.EndChange();
                                        currentRTBUser.Focus();
                                        src = "";
                                    }
                                }
                                break;
                            }
                            #endregion <a><img></a>
                            #region <a>
                            else
                            {
                                for (int k = 0; k < tag.Length;)
                                {
                                    while (tag[k] != '>')
                                    {
                                        k++;
                                    }
                                    k++;
                                    while (tag[k] != '<')
                                    {
                                        reference += tag[k];
                                        k++;
                                    }
                                    if (LinkDict.Count == 0)
                                    {
                                        Underline underline = new Underline(new Run(reference+" "));
                                        currentRTBUser.BeginChange();

                                        TextPointer tp = currentRTBUser.CaretPosition.GetPositionAtOffset(0,
                                                                                                          LogicalDirection
                                                                                                              .Forward);
                                        Span refContainer = new Span(underline, tp);
                                        currentRTBUser.CaretPosition = refContainer.ElementEnd;
                                        currentRTBUser.EndChange();
                                        currentRTBUser.Focus();
                                        LinkDict.Add(reference, reference);
                                        reference = "";
                                        break;
                                    }
                                    else
                                    {
                                        if (LinkDict.ContainsValue(reference))
                                        {
                                            reference = "";
                                            break;
                                        }
                                        else
                                        {
                                            Underline underline = new Underline(new Run(reference+" "));
                                            currentRTBUser.BeginChange();

                                            TextPointer tp = currentRTBUser.CaretPosition.GetPositionAtOffset(0,
                                                                                                              LogicalDirection
                                                                                                                  .Forward);
                                            Span refContainer = new Span(underline, tp);
                                            currentRTBUser.CaretPosition = refContainer.ElementEnd;
                                            currentRTBUser.EndChange();
                                            currentRTBUser.Focus();
                                            LinkDict.Add(reference, reference);
                                            reference = "";
                                            break;
                                        }
                                    }
                                }
                            }
                            #endregion <a>

                            tag = "";
                        }
                        #endregion <a></a>

                        #region <img>
                        if (mas[i].StartsWith("<img"))
                        {
                            {
                                int index = mas[i].IndexOf("src=", StringComparison.Ordinal);
                                string str = mas[i].Substring(index);
                                for (int k = 5; k < str.Length; k++)
                                {
                                    while (str[k] != '"')
                                    {
                                        src += str[k];
                                        k++;
                                    }
                                    break;
                                }
                                if (ImageDict == null)
                                {
                                    Image image = new Image();
                                    image.Stretch = Stretch.None;
                                    BitmapImage bmp = new BitmapImage(new Uri(src, UriKind.Relative));
                                    image.Source = bmp;
                                    currentRTBUser.BeginChange();
                                    TextPointer tp = currentRTBUser.CaretPosition.GetPositionAtOffset(0,
                                                                                                      LogicalDirection
                                                                                                          .Forward);
                                    InlineUIContainer imageContainer = new InlineUIContainer(image, tp);
                                    currentRTBUser.CaretPosition = imageContainer.ElementEnd;
                                    currentRTBUser.EndChange();
                                    currentRTBUser.Focus();
                                    src = "";
                                }
                                else
                                {
                                    if (ImageDict.ContainsValue(src))
                                    {
                                        src = "";
                                        break;
                                    }
                                    Image image = new Image();
                                    image.Stretch = Stretch.None;
                                    BitmapImage bmp = new BitmapImage(new Uri(src, UriKind.Relative));
                                    image.Source = bmp;
                                    currentRTBUser.BeginChange();
                                    TextPointer tp = currentRTBUser.CaretPosition.GetPositionAtOffset(0,
                                                                                                      LogicalDirection
                                                                                                          .Forward);
                                    InlineUIContainer imageContainer = new InlineUIContainer(image, tp);
                                    currentRTBUser.CaretPosition = imageContainer.ElementEnd;
                                    currentRTBUser.EndChange();
                                    currentRTBUser.Focus();
                                    src = "";
                                }
                            }
                            break;
                        }
                        #endregion <img>
                    }
                }
            }
        }

        //Calling, when TabItem changed
        private void TabControlMain_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            foreach (TabItem item in TabControlMain.Items.Cast<TabItem>().Where(item => item.IsSelected))
            {
                currentTab = item;

                addedTabControl = (TabControl) item.Content;
                TabItem editor = (TabItem) addedTabControl.Items[0];
                TabItem source = (TabItem) addedTabControl.Items[1];
                TabItem browser = (TabItem) addedTabControl.Items[2];
                currentRTBUser = (RichTextBox) editor.Content;
                currentRTBHtml = (RichTextBox) source.Content;
                currentWebBrowser = (WebBrowser) browser.Content;

                fileName = (string) item.Header;
                NewDocument.pageTitle = "";
                NewDocument.pageTitle = FindTitle(currentRTBHtml);
                NewDocument.pageBody = "";
                NewDocument.pageBody = FindBody(currentRTBHtml);
                UserText = new TextRange(currentRTBUser.Document.ContentStart, currentRTBUser.Document.ContentEnd).Text;
                HtmlText = new TextRange(currentRTBHtml.Document.ContentStart, currentRTBHtml.Document.ContentEnd).Text;
                dictionary["$title"] = NewDocument.pageTitle;
                dictionary["$DTD"] = NewDocument.pageDTD;
                dictionary["$html"] = NewDocument.pageHtmlType;
                return;
            }
        }

        //MenuItem "Open Project" click
        private void MenuItemOpenProject_Click(object sender, RoutedEventArgs e)
        {
            if (!TreeViewMain.Items.IsEmpty)
            {
                var result = MessageBox.Show("Old project will be removed! Continue?", "iSmart Creator",
                                             MessageBoxButton.YesNoCancel);

                if (result == MessageBoxResult.No || result == MessageBoxResult.Cancel)
                {
                    return;
                }
            }
            FolderBrowserDialog browser = new FolderBrowserDialog {ShowNewFolderButton = false};
            var resultFolder = browser.ShowDialog();
            if (resultFolder == System.Windows.Forms.DialogResult.OK)
            {
                TreeViewMain.Items.Clear();
                TabControlMain.Items.Clear();
                DirectoryNameWindow.MainTreeViewItem = new TreeViewItem();
                TreeViewMain.Items.Add(DirectoryNameWindow.MainTreeViewItem);
                projectFileDirectory = browser.SelectedPath;
                DirectoryInfo di = new DirectoryInfo(projectFileDirectory);
                DirectoryNameWindow.MainTreeViewItem.Header = di.Name;
                DirectoryNameWindow.MainTreeViewItem.IsExpanded = true;
                foreach (var file in di.GetFiles())
                {
                    FileStream stream = new FileStream(file.FullName, FileMode.Open);

                    string str;
                    fileName = file.Name;

                    StreamReader reader = new StreamReader(stream);
                    using (reader)
                    {
                        str = reader.ReadToEnd();
                    }

                    TabControl control = new TabControl {TabStripPlacement = Dock.Bottom};
                    TabItem editor = new TabItem {Header = "editor"};
                    TabItem sourceCode = new TabItem {Header = "source code"};
                    TabItem preview = new TabItem {Header = "preview"};

                    RichTextBox rtbHtmlCode = new RichTextBox
                        {
                            IsReadOnly = true,
                            VerticalScrollBarVisibility = ScrollBarVisibility.Auto,
                            HorizontalScrollBarVisibility = ScrollBarVisibility.Auto
                        };
                    RichTextBox rtbUserText = new RichTextBox
                        {
                            VerticalScrollBarVisibility = ScrollBarVisibility.Auto,
                            HorizontalScrollBarVisibility = ScrollBarVisibility.Auto
                        };
                    WebBrowser webBrowser = new WebBrowser();
                    TabItem item = new TabItem {Header = fileName};

                    FlowDocument flow = new FlowDocument();
                    Paragraph paragraph = new Paragraph();
                    paragraph.Inlines.Add(new Run(str));
                    flow.Blocks.Add(paragraph);
                    rtbHtmlCode.Document = flow;

                    editor.Content = rtbUserText;
                    sourceCode.Content = rtbHtmlCode;
                    preview.Content = webBrowser;

                    control.Items.Add(editor);
                    control.Items.Add(sourceCode);
                    control.Items.Add(preview);

                    item.Content = control;
                    item.IsSelected = true;
                    TabControlMain.Items.Add(item);
                    TabControlMain.Visibility = Visibility.Visible;

                    DirectoryNameWindow.MainTreeViewItem.Items.Add(file.Name);

                    try
                    {
                        currentRTBUser.TextChanged += currentRTBUser_TextChanged;
                    }
                    catch (NullReferenceException)
                    {

                    }
                }
                MenuItemCloseAll.IsEnabled = true;
                MenuItemAddSpecial.IsEnabled = true;
                MenuItemSave.IsEnabled = true;
                MenuItemSaveAs.IsEnabled = true;
                MenuItemOpenFile.IsEnabled = true;
                BtnNew.IsEnabled = true;
                BtnOpen.IsEnabled = true;
                BtnSave.IsEnabled = true;
                MenuItemChangeTitle.IsEnabled = true;
                BtnLink.IsEnabled = true;
                BtnImage.IsEnabled = true;
                BtnTable.IsEnabled = true;
            }
        }

        //Button "Add" click
        private void BtnNew_Click(object sender, RoutedEventArgs e)
        {
            var newFile = new NewFile {Owner = this};
            newFile.ShowDialog();

            try
            {
                currentRTBUser.Focus();
                currentRTBHtml.TextChanged += currentRTBHtml_TextChanged;
                currentRTBUser.TextChanged += currentRTBUser_TextChanged;
                UserText = new TextRange(currentRTBUser.Document.ContentStart, currentRTBUser.Document.ContentEnd).Text;
                HtmlText = new TextRange(currentRTBHtml.Document.ContentStart, currentRTBHtml.Document.ContentEnd).Text;
            }
            catch (NullReferenceException)
            {

            }
        }

        //Button "Open" click
        private void BtnOpen_Click(object sender, RoutedEventArgs e)
        {
            MenuItem_Click_5(sender, e);
        }

        //Button "Save" click
        private void BtnSave_Click(object sender, RoutedEventArgs e)
        {
            MenuItem_Click_4(sender, e);
        }

        //Users RTB TextChangedEvent
        private void currentRTBUser_TextChanged(object sender, TextChangedEventArgs e)
        {
            BtnUndo.IsEnabled = currentRTBUser.CanUndo;
            BtnRedo.IsEnabled = currentRTBUser.CanRedo;
            UserText = new TextRange(currentRTBUser.Document.ContentStart, currentRTBUser.Document.ContentEnd).Text;
            HtmlText = new TextRange(currentRTBHtml.Document.ContentStart, currentRTBHtml.Document.ContentEnd).Text;
            
            ArrayList list = new ArrayList();
            FlowDocument flow = new FlowDocument();
            ImageDict = new Dictionary<Image, string>();
            flow = currentRTBUser.Document;
            //flow.Blocks.Add(paragraph);
            foreach (Block block in flow.Blocks)
            {
                if (block is Paragraph)
                {
                    Paragraph paragraph = (Paragraph) block;
                    foreach (Inline inline in paragraph.Inlines)
                    {
                        if (inline is InlineUIContainer)
                        {
                            InlineUIContainer uiContainer = (InlineUIContainer) inline;
                            if (uiContainer.Child is Image)
                            {
                                Image image = (Image) uiContainer.Child;
                                ImageDict.Add(image, image.Source.ToString());
                            }
                        }
                    }
                }
            }

            string[] mas = HtmlText.Split('\n');
            foreach (var i in mas)
            {
                list.Add(i);
            }
            #region remove image from html text if removed from user
            for (int i = 0; i < list.Count; i++)
            {
                if (list[i].ToString().Contains("<img"))
                {
                    int index = list[i].ToString().IndexOf("src=", StringComparison.Ordinal);
                    string str = list[i].ToString().Substring(index);
                    string src = "";
                    for (int k = 5; k < str.Length; )
                    {
                        while (str[k] != '"')
                        {
                            src += str[k];
                            k++;
                        }
                        break;
                    }
                    if (!ImageDict.ContainsValue(src))
                    {
                        list.Remove(list[i]);
                    }
                }
            }
            #endregion

            #region AddText

            string[] user = UserText.Split('\n');
            for (int i = 0; i < user.Length; i++)
            {
                if (user[i] == "\r")
                {
                    if (i == 0)
                    {
                        continue;
                    }
                    user[i] = user[i].Replace("\r", "<br>");
                }
                else if (user[i].Contains("\r"))
                {
                    user[i] = user[i].Replace("\r", "");
                }
            }
            user = GoldClear(user);
            string body = "";

            for (int i = 0; i < list.Count; i++)
            {
                if (list[i].ToString() == "<body>")
                {
                    i++;
                    while (list[i].ToString() != "</body>")
                    {
                        if (list[i].ToString().StartsWith("<"))
                        {
                            body += list[i].ToString();
                        }
                        i++;
                    }
                    break;
                }
            }

            list = ClearBody(list);
            //body = user.Aggregate(body, (current, s) => current + s);
            foreach (var s in user)
            {
                body += s;
            }
            list = NewBody(list, body);
            #endregion
            //string[] user = UserText.Split('\n');
            //string body = FindBody(currentRTBHtml);
            //list = ClearBody(list);

            //foreach (var s in user)
            //{
            //    if (s == "\r")
            //    {
            //        body += "<br>";
            //    }
            //}

            //list = NewBody(list, body);
            
            #region clearAfterHtmlEnd

            for (int i = 0; i < list.Count; )
            {
                while (list[i].ToString() != "</html>")
                {
                    i++;
                }
                try
                {
                    i++;
                    while (true)
                    {
                        list.Remove(list[i]);
                    }
                }
                catch (ArgumentOutOfRangeException)
                {
                    break;
                }
            }

            #endregion
            
            #region newbody

            Paragraph p = new Paragraph();
            FlowDocument f = new FlowDocument();
            currentRTBHtml.BeginChange();
            currentRTBHtml.Document.Blocks.Clear();
            foreach (var i in list)
            {
                p.Inlines.Add(i + "\n");
            }
            f.Blocks.Add(p);
            currentRTBHtml.EndChange();
            currentRTBHtml.Document = f;
            #endregion newbody
        }

        private ArrayList ClearBody(ArrayList list)
        {
            for (int i = 0; i < list.Count; i++)
            {
                if (list[i].ToString() == "<body>")
                {
                    i++;
                    while (list[i].ToString() != "</body>")
                    {
                        list.Remove(list[i]);
                    }
                    break;
                }
            }
            return list;
        }

        private ArrayList NewBody(ArrayList list, string body)
        {
            for (int i = 0; i < list.Count; i++)
            {
                if (list[i].ToString() == "<body>")
                {
                    list.Insert(i + 1, body);
                    break;
                }
            }
            return list;
        }

        //Find title
        public static string FindTitle(RichTextBox rtb)
        {
            string allHtmlText = new TextRange(rtb.Document.ContentStart, rtb.Document.ContentEnd).Text;

            string pattern = @"<title>|</title>";
            string title = "";
            string[] htmlText = allHtmlText.Split('\n');
            foreach (var s in htmlText)
            {
                if (s.StartsWith("<title>"))
                {
                    title = Regex.Replace(s, pattern, String.Empty);
                    break;
                }
            }
            return title;
        }

        //Find body
        public static string FindBody(RichTextBox rtb)
        {
            string allHtmlText = new TextRange(rtb.Document.ContentStart, rtb.Document.ContentEnd).Text;
            string body = "";
            //if (NewDocument.pageBody != null)
            //{
            //    return ;
            //}
            string[] str = allHtmlText.Split('\n');
            for (int i = 0; i < str.Length; i++)
            {
                if (str[i] == "<body>")
                {
                    i++;
                    while (str[i] != "</body>")
                    {
                        body += str[i] + "\n";
                        i++;
                    }
                    break;
                }
            }
            return body;
        }

        //MenuItem "Change Title" click
        private void MenuItemChangeTitle_Click(object sender, RoutedEventArgs e)
        {
            var changeTitle = new DocumentTitleWindow {Owner = this};
            changeTitle.ShowDialog();
        }

        //Button "Undo" click
        private void BtnUndo_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                currentRTBUser.Undo();
            }
            catch (NullReferenceException)
            {
                MessageBox.Show("Document is empty!", "iSmart Creator");
            }
        }

        //Button "Redo" click
        private void BtnRedo_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                currentRTBUser.Redo();
            }
            catch (NullReferenceException)
            {
                MessageBox.Show("Document is empty!", "iSmart Creator");
            }
        }

        //Button "Link" click
        private void BtnLink_Click(object sender, RoutedEventArgs e)
        {
            currentRTBUser.TextChanged-=currentRTBUser_TextChanged;
            var link = new LinkAddWindow {Owner = this};
            link.ShowDialog();
        }

        //Clear some auto-generated strings as "" and "\r"
        public static string[] GoldClear(string[] mas)
        {
            ArrayList list = new ArrayList();
            foreach (var i in mas)
            {
                list.Add(i);
            }

            try
            {
                for (int i = 0; i < list.Count; i++)
                {
                    if (list[i].ToString() == "")
                    {
                        list.Remove(list[i]);
                    }

                    if (list[i].ToString() == "\r")
                    {
                        list.Remove(list[i]);
                    }

                    if (list[i].ToString() == "")
                    {
                        list.Remove(list[i]);
                    }
                }
            }
            catch (ArgumentOutOfRangeException)
            {

            }
            return (string[]) list.ToArray(typeof (string));
        }

        //Button "Image" click
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            var image = new ImageAddWindow {Owner = this};
            image.ShowDialog();
        }

        //Button "Table" click
        private void BtnTable_Click(object sender, RoutedEventArgs e)
        {
            var table = new TableAddWindow {Owner = this};
            table.ShowDialog();
        }

        //Button "Delete" click
        private void BtnDelete_Click(object sender, RoutedEventArgs e)
        {
            MenuItem_Click_2(sender, e);
        }

        //Button "New Folder" click
        private void BtnNewFolder_Click(object sender, RoutedEventArgs e)
        {
            MenuItem_Click_1(sender, e);
        }

        private void BtnItalic_Click(object sender, RoutedEventArgs e)
        {
            TextSelection selectedText = currentRTBUser.Selection;
            if (selectedText.Text != "")
            {
                TextPointer startPosition = selectedText.Start;
                TextPointer endPosition = selectedText.End;
                ArrayList list = new ArrayList();

                currentRTBUser.Selection.Select(startPosition, endPosition);
                selectedText.ApplyPropertyValue(TextElement.FontStyleProperty, FontStyles.Italic);
                string str = selectedText.Text;
                string body = FindBody(currentRTBHtml);
                body = body.Replace(str, "<i>" + str + "</i>");
                string[] mas = HtmlText.Split('\n');
                foreach (var i in mas)
                {
                    list.Add(i);
                }
                list = ClearBody(list);
                list = NewBody(list, body);
                Paragraph p = new Paragraph();
                FlowDocument f = new FlowDocument();
                currentRTBHtml.BeginChange();
                currentRTBHtml.Document.Blocks.Clear();
                foreach (var i in list)
                {
                    p.Inlines.Add(i + "\n");
                }
                f.Blocks.Add(p);
                currentRTBHtml.EndChange();
                currentRTBHtml.Document = f;
                selectedText.Select(endPosition,endPosition);
                selectedText.ApplyPropertyValue(TextElement.FontStyleProperty, FontStyles.Normal);
            }
        }

        private void BtnBold_Click(object sender, RoutedEventArgs e)
        {
            TextSelection selectedText = currentRTBUser.Selection;
            if (selectedText.Text != "")
            {
                TextPointer startPosition = selectedText.Start;
                TextPointer endPosition = selectedText.End;
                ArrayList list = new ArrayList();

                currentRTBUser.Selection.Select(startPosition, endPosition);
                selectedText.ApplyPropertyValue(TextElement.FontWeightProperty, FontWeights.Bold);
                string str = selectedText.Text;
                string body = FindBody(currentRTBHtml);
                body = body.Replace(str, "<b>" + str + "</b>");
                string[] mas = HtmlText.Split('\n');
                foreach (var i in mas)
                {
                    list.Add(i);
                }
                list = ClearBody(list);
                list = NewBody(list, body);
                Paragraph p = new Paragraph();
                FlowDocument f = new FlowDocument();
                currentRTBHtml.BeginChange();
                currentRTBHtml.Document.Blocks.Clear();
                foreach (var i in list)
                {
                    p.Inlines.Add(i + "\n");
                }
                f.Blocks.Add(p);
                currentRTBHtml.EndChange();
                currentRTBHtml.Document = f;
                selectedText.Select(endPosition,endPosition);
                selectedText.ApplyPropertyValue(TextElement.FontStyleProperty, FontStyles.Normal);
            }
        }

        private void BtnBold2_Click(object sender, RoutedEventArgs e)
        {
            BtnBold_Click(sender, e);
        }

        private void BtnItalic2_Click(object sender, RoutedEventArgs e)
        {
            BtnItalic_Click(sender, e);
        }

        private void BtnUnderline_Click(object sender, RoutedEventArgs e)
        {
            TextSelection selectedText = currentRTBUser.Selection;
            if (selectedText.Text != "")
            {
                TextPointer startPosition = selectedText.Start;
                TextPointer endPosition = selectedText.End;
                ArrayList list = new ArrayList();

                currentRTBUser.Selection.Select(startPosition, endPosition);
                selectedText.ApplyPropertyValue(Run.TextDecorationsProperty, TextDecorations.Underline);
                string str = selectedText.Text;
                string body = FindBody(currentRTBHtml);
                body = body.Replace(str, "<u>" + str + "</u>");
                string[] mas = HtmlText.Split('\n');
                foreach (var i in mas)
                {
                    list.Add(i);
                }
                list = ClearBody(list);
                list = NewBody(list, body);
                Paragraph p = new Paragraph();
                FlowDocument f = new FlowDocument();
                currentRTBHtml.BeginChange();
                currentRTBHtml.Document.Blocks.Clear();
                foreach (var i in list)
                {
                    p.Inlines.Add(i + "\n");
                }
                f.Blocks.Add(p);
                currentRTBHtml.EndChange();
                currentRTBHtml.Document = f;
                selectedText.Select(endPosition, endPosition);
                selectedText.ApplyPropertyValue(TextElement.FontStyleProperty, FontStyles.Normal);
            }
        }
    }
}